package zzxkj.blog.controller.admin;

import com.google.code.kaptcha.Producer;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import zzxkj.blog.common.lang.Consts;
import zzxkj.blog.service.UserService;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * 登录请求处理
 * @author zzxkj
 */
@Slf4j
@Controller
@RequestMapping("/admin")
public class LoginController {
    private final UserService userService;
    private final Producer producer;
    final
    HttpSession session;
    public LoginController(UserService userService, Producer producer, HttpSession session) {
        this.userService = userService;
        this.producer = producer;
        this.session = session;
    }

    /**
     * 验证码
     * */
    @GetMapping("/captcha.jpg")
    public void kaptcha(HttpServletResponse response, HttpServletRequest request) throws IOException {
        //生成验证码
        String text = producer.createText();
        //在session中存放
        session.setAttribute(Consts.CAPTCHA_SESSION_KEY, text);
        //验证码转为字节流
        BufferedImage image = producer.createImage(text);
        //禁止缓存
        response.setHeader("Cache-Control","no-store,no-cache");
        //声明为图片类型
        response.setContentType("image/jpeg");
        //将流发送到浏览器
        ServletOutputStream outputStream = response.getOutputStream();
        ImageIO.write(image,"jpg",outputStream);
    }
    @GetMapping
    public String loginPage(HttpServletRequest request) {
        return "admin/login";
    }

    @PostMapping("/login")
    public String login(@RequestParam String username,
                        @RequestParam String password,
                        @RequestParam String captcha,
                        HttpSession session,
                        RedirectAttributes attributes) {

        //User user = userService.checkUser(username, password);
        if (username == null) {
            attributes.addFlashAttribute("message","用户名不能为空");
            return "redirect:/admin";
        } else if (captcha==null){
            attributes.addFlashAttribute("message","验证码不能为空");
            return "redirect:/admin";
        } else if(!captcha.equals(session.getAttribute(Consts.CAPTCHA_SESSION_KEY))){
            attributes.addFlashAttribute("message","验证码错误");
            return "redirect:/admin";
        }
        //MD5加密在DAO层
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try{
            //登录
            SecurityUtils.getSubject().login(token);
            //手动触发认证
            SecurityUtils.getSubject().hasRole("admin");
        }catch (AuthenticationException e) {
            if (e instanceof UnknownAccountException) {
                attributes.addFlashAttribute("message","用户不存在");
            } else if (e instanceof LockedAccountException) {
                attributes.addFlashAttribute("message","用户被禁用");
            } else if (e instanceof IncorrectCredentialsException) {
                attributes.addFlashAttribute("message","密码错误");
            } else {
                attributes.addFlashAttribute("message","用户认证失败");
            }
            return "redirect:/admin";
        }
        //如果是管理员用户，跳转到后台管理界面
        if(userService.isAdminUser(username)){
            return "redirect:/admin/index";
        }
        return "redirect:/";
    }

    @GetMapping("/logout")
    public String logout(HttpSession session) {
        // shiro退出
        SecurityUtils.getSubject().logout();
        return "redirect:/admin";
    }

}
